(function($){
	var KEY = "jforest.table";
	
	var Cell=function(index,code,value){
		this.index=index,this.code=code;this.value=value;
	}
	Cell.prototype={
		update:function(){
			if(jf.isNotNull(this.newValue)){this.value=this.newValue;this.newValue=null;delete this.newValue;}
		}
	}
	
	/* 文本列 */
	var TextColumn=function(options){
		this.options=$.extend({},options);
		this.arrCells = [];
	}
	TextColumn.prototype={
		createThEl:function(){return $('<th></th>').html(this.options.title).width(this.options.width);},
		createTdEl:function(table,index,record,$tr){
			var opts=this.options,cell=new Cell(index,opts.code,record[opts.code]);
			if($.isFunction(this.options.format)){
				cell.value = this.options.format.apply(table,[record]);
			}
			cell.$td=$('<td></td>').append(cell.value);
			this.arrCells[index]=cell;return cell.$td;
		}
	}
	/* 按钮列 */
	var IconColumn=function(options){
		this.options=$.extend({width:'80px'},options);
		if(!$.isFunction(this.options.icons)){this.options.width = 20+30*this.options.icons.length;}
		this.arrEl = [];
	}
	IconColumn.prototype={
		createThEl:function(){return $('<th></th>').html(this.options.title).width(this.options.width);},
		createTdEl:function(table,index,record,$tr){
			var $td=$('<td></td>').width(this.options.width),icons=[];
			if($.isFunction(this.options.icons)){icons = this.options.icons.apply(table,[record,$tr]);}
			else{icons = this.options.icons;}
			$.each(icons,function(i,item){
				$a = $('<a href="javascript:void(0);" style="margin-right:10px;"></a>');
				if(item.icon){$a.append('<i class="fa '+item.icon+'"></i>');}
				if(item.tooltip){if(item.icon){$a.tooltip({title:item.tooltip});}else{$a.html(item.tooltip)}}
				$a.appendTo($td).click(function(e){item.click.apply(table,[record,$tr,e]);});
			});
			this.arrEl.push($td);return $td;
		}
	}
	/* 复选框列 */
	var CheckboxColumn=function(options){
		this.options=$.extend({},options);
		this.arrCells = [];
	}
	CheckboxColumn.prototype={
		createThEl:function(){
			var opts=this.options,col=this;
			this.$checkbox = $('<label class="nice-checkbox"><input type="checkbox"></label>');
			this.$checkbox.mousedown(function(event){
				$(this).toggleClass('on');
				if($(this).hasClass('on')){
					$.each(col.arrCells,function(i,cell){
						cell.$td.find('.nice-checkbox').addClass('on');
						cell.$td.find('.nice-checkbox input[type="checkbox"]')[0].checked = true;
					});
				}else{
					$.each(col.arrCells,function(i,cell){
						cell.$td.find('.nice-checkbox').removeClass('on');
						cell.$td.find('.nice-checkbox input[type="checkbox"]')[0].checked = false;
					});
				}
			});
			if(opts.click){
				this.$checkbox.find('input[type="checkbox"]').click(function(){
					opts.click.apply(col,[null]);
				});
			}
			if(opts.values && !$.isArray(opts.values)){
				opts.values = opts.values.split(",");
			}
			return $('<th></th>').append(this.$checkbox).width(this.options.width);
		},
		createTdEl:function(table,index,record,$tr){
			var opts=this.options,cell=new Cell(index,opts.code,record[opts.code]),col=this;
			cell.$td = $('<td><label class="nice-checkbox"><input type="checkbox" value="'+cell.value+'"></label></td>');
			cell.$td.find('.nice-checkbox').mousedown(function(event){
				$(this).toggleClass('on');
			});
			if(opts.click){
				cell.$td.find('.nice-checkbox input[type="checkbox"]').click(function(){
					opts.click.apply(col,[cell.value]);
				});
			}
			if(opts.values && $.inArray(cell.value.toString(),opts.values) > -1){
				cell.$td.find('.nice-checkbox').addClass('on');
				cell.$td.find('.nice-checkbox input[type="checkbox"]')[0].checked = true;
			}
			
			this.arrCells.push(cell);
			return cell.$td;
		},
		getCheckboxValues:function(){
			var values = '';
			$.each(this.arrCells,function(i,cell){
				var $checkbox = cell.$td.find('.nice-checkbox input[type="checkbox"]');
				if($checkbox[0].checked == true){
					values = values+','+$checkbox.val();
				}
			});
			if(values.length>1){values = values.substring(1);}
			return values;
		}
	}
	/* 可编辑列 */
	var InputColumn=function(options){
		this.options=$.extend({},options);
		this.arrCells = [];
	}
	InputColumn.prototype={
		createThEl:function(){return $('<th></th>').html(this.options.title).width(this.options.width);},
		createTdEl:function(table,index,record,$tr){
			var opts=this.options,cell=new Cell(index,opts.code,record[opts.code]),col=this;
			cell.$td=$('<td></td>').data('_editing',false).width(opts.width);
			if(opts.inputType=='text'){
				cell.$inputEl=$('<input type="text" class="form-control" style="display:none;" value="'+cell.value+'"/>').appendTo(cell.$td);
			}else if(opts.inputType=='checkbox'){
				cell.$inputEl=$('<input type="checkbox" style="display:none;"/>').appendTo(cell.$td);
				cell.$inputEl[0].checked=cell.value;
			}
			cell.$textEl=$('<span style="width:100%;height:100%;">'+cell.value+'</span>').appendTo(cell.$td);
			cell.$td.dblclick(function(){
				if($(this).data('_editing')==true){
					$(this).data('_editing',false);
					if(opts.inputType=='checkbox'){
						cell.newValue=cell.$inputEl[0].checked;
					}else{cell.newValue=cell.$inputEl.val();}
					if(cell.value!==cell.newValue){
						//触发保存事件
						table._editCellData(record,cell);
					}
				}else{$(this).data('_editing',true);}
				cell.$textEl.toggle();cell.$inputEl.toggle().focus();
			});
			this.arrCells[index]=cell;return cell.$td;
		}
	}
	/* 详细描述列 */
	var DetailColumn=function(options){
		this.options=$.extend({
			width:30,
			detailFormat:function(){}
		},options);
		this.arrCells = [];
	}
	DetailColumn.prototype={
		createThEl:function(){return $('<th></th>').html(this.options.title).width(this.options.width);},
		createTdEl:function(table,index,record,$tr){
			var opts=this.options,cell=new Cell(index,opts.code,record[opts.code]),col=this,colsNum=table.options.cols.length;
			cell.$td = $('<td><a href="javascript:void(0);"><i class="fa fa-plus-square"></i></a></td>');
			cell.$td.width(this.options.width);
			cell.$td.find('a').click(function(){
				var $detailTr = cell.$td.data('_detailTr');
			
				$(this).find('i').toggleClass('fa-plus-square');
				$(this).find('i').toggleClass('fa-minus-square');
				
				if(!$detailTr){
					$detailTr = $('<tr><td colspan="'+colsNum+'"></td></tr>');
					$detailTr.find('td').html(opts.detailFormat.apply(opts,[record]));
					cell.$td.data('_detailTr',$detailTr);
				}
				
				if($(this).find('i').hasClass('fa-minus-square')){
					$tr.after($detailTr);
				}else{
					$detailTr.remove();
				}
			});
			this.arrCells[index]=cell;return cell.$td;
		}
	}
	
	var Table = function(element,options){
		this.$el = $(element);
		this.options = $.extend({
			autoLoad:true,
			ajax:{},
			editAjax:null,
			pagingEl:'auto',
			paging:{},
			cols:null //{}或[]
		},options);
		if(this.$el.find('thead').length==0){this.$el.append('<thead></thead>');}
		if(this.$el.find('tbody').length==0){this.$el.append('<tbody></tbody>');}
		if(this.$el.find('tfoot').length==0){this.$el.append('<tfoot></tfoot>');}
	
		this.ajax=jf.getAjax($.extend({param:null},
			this.options.ajax,
			{bindObj:this,
			param:function(param){
				var optsAjax = this.options.ajax;
				if(this.paging){
					var pagingOpts=this.paging.options;
					var data = {pageNo:pagingOpts.pageNo,pageLimit:pagingOpts.pageLimit};
					if($.isFunction(optsAjax.param)){
						return optsAjax.param.apply(this,[data]);
					}else if(optsAjax.param){
						return $.extend({},optsAjax.param,data);
					}else{
						return data;
					}
				}else if($.isFunction(optsAjax.param)){
					return optsAjax.param.apply(this);
				}else if(optsAjax.param){
					return optsAjax.param;
				}else{return {};}
			},
			callback:function(result){
				if($.isFunction(this.options.ajax.callback)){result=this.options.ajax.callback.apply(this,[result])};
				if(result){if($.isArray(result)){this._buildData(result);}
					else if($.isArray(result.data)){this._buildData(result.data);};
					if(this.paging){this.paging.setData({dataTotal:result.dataTotal,pageTotal:result.pageTotal});}}
			}}
		));
		if(this.options.editAjax){
			this.editAjax=jf.getAjax($.extend({},this.options.editAjax,{
				bindObj:this,
				param:{},
				callback:function(){}
			}));
		}
		this._buildTitle();var table=this;
		if('auto'==this.options.pagingEl){
			this.options.pagingEl=$('<tr><td colspan="'+this.options.cols.length+'"></td></tr>').appendTo(this.$el.find('tfoot')).find('td');}
		if(this.options.pagingEl){this.paging=$(this.options.pagingEl).jfPaging($.extend(this.options.paging,{
			callback:function(opts){table.ajax.load(function(param){return $.extend(param||{},{pageNo:opts.pageNo,pageLimit:opts.pageLimit});});}
		}));this.paging.$el.addClass('pagination-sm').css('margin',0)}
		//是否自动加载
		if(this.options.autoLoad == true){this.loadData();}
	}
	
	Table.prototype = {
		_buildTitle:function(){
			var cols=this.options.cols||{},opts=this.options,table=this;
			if($.isArray(cols)){
				var $tr=$('<tr></tr>');
				$.each(cols,function(i,v){
					var col=null;
					if(v.icons){col=new IconColumn(v);}
					else if(v.inputType){col=new InputColumn(v);}
					else if(v.detailFormat){col=new DetailColumn(v);}
					else if(v.checkbox){col=new CheckboxColumn(v);}
					else {col=new TextColumn(v);}
					$tr.append(col.createThEl());
					opts.cols[i] = col;
				});
				this.$el.find('thead').append($tr);
			}else{
				var arrCol=[];
				this.$el.find('thead th').each(function(i,th){
					var code=$(th).attr('data-code'),col=cols[code],title=$(th).html(),width=$(th).width();
					col=$.extend({code:code,title:title,width:width},col||{});
					if(col.icons){col=new IconColumn(col);}
					else if(col.inputType){col=new InputColumn(col);}
					else if(col.detailFormat){col=new DetailColumn(col);}
					else if(col.checkbox){col=new CheckboxColumn(col);}
					else {col=new TextColumn(col);}
					arrCol.push(col);
				})
				this.options.cols=arrCol;
			}
		},
		_buildData:function(data){
			this.$el.find('tbody').empty();
			var self = this;
			$.each(data,function(i,record){
				var $tr = $('<tr></tr>');
				$.each(self.options.cols,function(j,col){
					$tr.append(col.createTdEl(self,j,record,$tr));
				});
				self.$el.find('tbody').append($tr);
			})
		},
		_editCellData:function(record,cell){
			var opts_ea=this.options.editAjax,data;
			if(this.editAjax.isValid()){
				if($.isFunction(opts_ea.param)){
					data = opts_ea.param.apply(this,[record,cell.code,cell.newValue]);
				}else{
					data = $.extend({},opts_ea.param||{},{
						name:cell.cell,
						value:cell.newValue
					});
				}
				this.editAjax.load(data,function(result){
					if($.isFunction(opts_ea.callback)){
						if(opts_ea.callback.apply(this,[result])==true){
							cell.update();cell.$textEl.html(cell.value);
						}
					}else {cell.update();cell.$textEl.html(cell.value);}
				});
			}
		},
		loadData:function(args){
			if(this.ajax.isValid()){this.ajax.load(args);}
		}
	}
	
	$.fn.jfTable = function(){
		var args = Array.prototype.slice.call(arguments, 0);
		var value = undefined;
		this.each(function () {
			var $this = $(this);
			//throw 'only support table element'
			if (args.length === 0 || typeof(args[0]) === "object") {
				opts = args.length === 0 ? {} : $.extend({}, args[0]);
				$this.data(KEY,new Table(this,opts)); //创建控件
			}else if (typeof(args[0]) === "string"){
				var entity = $this.data(KEY);
                if(entity === undefined){return;}
                value = entity[args[0]].apply(entity, args.slice(1));
			}else{
				 throw 'Invalid arguments to '+KEY+' plugin: ' + args;
			}
	    });
	    return (value === undefined) ? this : value;
	};
	
	$.fn.jfTable.Constructor = Table;
})(window.jQuery)